package pl.edu.agh.ros.node;

import java.util.List;

import org.jivesoftware.smack.packet.Message;
import org.ros.message.MessageListener;
import org.ros.node.DefaultNodeFactory;
import org.ros.node.NodeConfiguration;

import pl.edu.agh.ros.node.conf.ProxyNodeConfiguration;
import pl.edu.agh.ros.node.conf.XMPPConfiguration;
import pl.edu.agh.ros.node.manager.IServerManager;
import pl.edu.agh.ros.node.manager.XMPPManager;
import pl.edu.agh.ros.node.util.RosMessageUtils;

import com.google.common.base.Preconditions;

//TODO -maybe LiteProxySubscriber that sends only to rosTopicManager(provider)
public class ProxySubscriber<T extends org.ros.message.Message> extends AbstractProxyNode {

	protected final RosMessageUtils<T> rosMessageUtils;
	private String loggedUser;

	public ProxySubscriber(IServerManager serverManager, XMPPConfiguration xmppConfiguration,
			ProxyNodeConfiguration proxyNodeConfiguration, String nodeName) {
		super(serverManager, xmppConfiguration, proxyNodeConfiguration, nodeName);
		this.rosMessageUtils = new RosMessageUtils<T>();
	}

	@Override
	public void main(NodeConfiguration nodeConfiguration) throws Exception {
		Preconditions.checkState(node == null);
		Preconditions.checkNotNull(nodeConfiguration);

		try {
			xmppConnector = new XMPPManager();
			xmppConnector.connectAndLogin(xmppConfiguration);
			loggedUser = xmppConnector.getConnection().getUser().split("/")[0]; //$NON-NLS-1$

			node = new DefaultNodeFactory().newNode(nodeName, nodeConfiguration);
			node.newSubscriber(proxyNodeConfiguration.getName(), proxyNodeConfiguration.getType(),
					new MessageListener<T>() {
						@Override
						public void onNewMessage(T message) {
							Message xmppMessage = rosMessageUtils.serializeMessage(message, node,
									proxyNodeConfiguration.getType());
							xmppMessage.setFrom(loggedUser);
							sendXMPPMessage(xmppMessage);
						}
					});
			// TODO change to log4j
			System.out.println("ProxySubscriber running"); //$NON-NLS-1$

		} catch (Exception e) {
			if (node != null) {
				node.getLog().fatal(e);
			} else {
				e.printStackTrace();
			}
		}
	}

	protected void sendXMPPMessage(Message message) {
		List<String> subscribers = serverManager.getSubscribers(proxyNodeConfiguration.getName());
		subscribers.remove(loggedUser);
		for (String subscriber : subscribers) {
			xmppConnector.sendMessage(message, subscriber);
		}
	}

}
